<?php

namespace sframe;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * 事件订阅器
 * Class Subscriber
 * @package app
 */
class Subscriber implements EventSubscriberInterface
{
	protected $debug;

	public function __construct($debug = false)
	{
		$this->debug = $debug;
	}

	public static function getSubscribedEvents()
	{
		return [

			KernelEvents::EXCEPTION => [
				['processException', 255],
				['logException', 254],
				['notifyException', -10],
			],

			KernelEvents::FINISH_REQUEST => [
				['onFinishRequest', 0]
			],

			KernelEvents::RESPONSE => [
				['onKernelResponsePre', 255],
				['onKernelResponsePost', -255],
			],

			KernelEvents::VIEW => [
				['onView', 0]
			],

			KernelEvents::TERMINATE => [
				['onTerminate', 0]
			],
		];
	}

	/**
	 * 处理异常
	 * @param GetResponseForExceptionEvent $event
	 */
	public function processException(GetResponseForExceptionEvent $event)
	{

	}

	/**
	 * 记录异常日志
	 * @param GetResponseForExceptionEvent $event
	 */
	public function logException(GetResponseForExceptionEvent $event)
	{
		ExceptionHandler::record($event->getException(), $this->debug, "Subscriber");
	}

	/**
	 * 自定义错误显示页面
	 * @param GetResponseForExceptionEvent $event
	 */
	public function notifyException(GetResponseForExceptionEvent $event)
	{
		ExceptionHandler::notify($event->getException(), $this->debug);
	}

	public function onFinishRequest(FinishRequestEvent $event)
	{

	}

	public function onKernelResponsePre(FilterResponseEvent $event)
	{
		$time = microtime();
		$response = $event->getResponse();
		$headers = $response->headers;
		//$headers->set('X-Before', $time);
		$headers->set('X-Powered-By', 'SFrame');
		$response->setContent($response->getContent());
	}

	public function onKernelResponsePost(FilterResponseEvent $event)
	{
		$time = microtime();
		$response = $event->getResponse();
		$headers = $response->headers;
		//$headers->set('X-Finish', $time);
		$response->setContent($response->getContent());

		if (!$headers->has('Content-Length') && !$headers->has('Transfer-Encoding') && !$response->isRedirection()) {
			$headers->set('Content-Length', strlen($response->getContent()));
		}
	}

	public function onView(GetResponseForControllerResultEvent $event)
	{
		//可以对控制器响应结果进一步处理
		$response = $event->getControllerResult();
		$toJson = false;

		if (!$response instanceof Response) {
			if (is_null($response)) {
				$response = "";
			}
			if(is_array($response) || is_object($response)) {
				$toJson = true;
				$response = json_encode($response);
			}
			if (!is_string($response)) {
				$response = var_export($response, true);
			}
			$event->setResponse(new Response($response));
		}

		if ($toJson) {
			$response = $event->getResponse();
			$response->headers->set('Content-Type', 'application/json');
		}
	}

	/**
	 * 完成响应，关闭连接之后，继续干一些后台任务
	 * @param PostResponseEvent $event
	 */
	public function onTerminate(PostResponseEvent $event)
	{
		//$log = "test";
		//put_file_contents($log, "onTerminate");
	}
}
